﻿using BotDetector.Core.NaiveBayesModule;
using BotDetector.Core.SVMModule;
using BotDetector.Core.TextPreprocessing;
using BotDetector.Core.Utilities;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BotDetector.Core
{
    public static class DetectorTrainer
    {
        private static TextPreprocessor textPreprocessor = new TextPreprocessor();
        private static FileOperator fileOperator = new FileOperator();

        private static string CLASSIFIER_PATH;
        private static string CLASSIFIER_TRAIN_PATH;
        private static string NONBOT_FOLDER_PATH;
        private static string BOT_FOLDER_PATH;
        private static string NONBOT_QUEUE_FOLDER_PATH;
        private static string BOT_QUEUE_FOLDER_PATH;
        private static string rootPath;

        private static TrainerStatus status = TrainerStatus.Trained;
        public static TrainerStatus Status { get { return status; } }
        
        static DetectorTrainer()
        {
            rootPath = Path.GetDirectoryName(Path.GetDirectoryName(System.AppDomain.CurrentDomain.BaseDirectory));
            CLASSIFIER_PATH = rootPath + Constants.ClassifierPath;
            NONBOT_FOLDER_PATH = rootPath + Constants.NonbotTrainPath;
            BOT_FOLDER_PATH = rootPath + Constants.BotTrainPath;
            NONBOT_QUEUE_FOLDER_PATH = rootPath + Constants.NonbotQueuePath;
            BOT_QUEUE_FOLDER_PATH = rootPath + Constants.BotQueuePath;
            CLASSIFIER_TRAIN_PATH = rootPath + Constants.ClassifierTrainPath;
        }

        public static void Train()
        {
            if (SearchNewTrainFiles())
            {
                CreateConfigurationFiles();

                fileOperator.DeleteFiles(CLASSIFIER_PATH);
                fileOperator.CopyFiles(CLASSIFIER_TRAIN_PATH, CLASSIFIER_PATH);
                fileOperator.DeleteFiles(CLASSIFIER_TRAIN_PATH);

                DetectorCreator.Create();
            }
            status = TrainerStatus.Trained;
        }

        public static void CreateConfigurationFiles()
        {
            status = TrainerStatus.UnderTraining;

            textPreprocessor = new TextPreprocessor();
            PreprocessNewTrainFiles();

            BayesTrainer bayesTrainer = new BayesTrainer(); ;
            SvmTrainer svmTrainer = new SvmTrainer();

            bayesTrainer.CreateTrainFile();
            svmTrainer.CreateTrainFile();
        }

        private static bool SearchNewTrainFiles()
        {
            bool result = true;
            result &= (!fileOperator.IsDirectoryEmpty(NONBOT_QUEUE_FOLDER_PATH));
            result &= (!fileOperator.IsDirectoryEmpty(BOT_QUEUE_FOLDER_PATH));

            return result;
        }

        private static void PreprocessNewTrainSet(string queueFolder, string destinationFolder)
        {
            List< Tuple<string, string> > newTrainSet = fileOperator.ReadFileSetAndNames(queueFolder);
            List< Tuple<string, string> > processedSet = new List<Tuple<string, string>>();

            foreach (Tuple<string, string> s in newTrainSet)
            {
                var preprocessText = textPreprocessor.Preprocess(s.Item2);
                var path = Path.Combine(destinationFolder, s.Item1);
                Tuple<string, string> element = new Tuple<string, string>(path, preprocessText);
                processedSet.Add(element);
            }

            fileOperator.WriteFileSet(processedSet);
            fileOperator.DeleteFiles(queueFolder);
        }

        private static void PreprocessNewTrainFiles()
        {
            PreprocessNewTrainSet(NONBOT_QUEUE_FOLDER_PATH, NONBOT_FOLDER_PATH);
            PreprocessNewTrainSet(BOT_QUEUE_FOLDER_PATH, BOT_FOLDER_PATH);
        }
    }
}
